/*
 * MIT License
 *
 * Copyright (c) 2020 wen.gu <454727014@qq.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

 /***************************************************************************
 * Name: cbus_service.c
 *
 * Purpose: implementation service side for cbus
 *
 * Developer:
 *   wen.gu , 2022-02-16
 *
 * TODO:
 *
 ***************************************************************************/

 /******************************************************************************
 **    INCLUDES
 ******************************************************************************/

#include "cbus_service_private.h"

#include "cbus/core/cbus_log.h"
/******************************************************************************
 **    MACROS
 ******************************************************************************/

/******************************************************************************
 **    VARIABLE DEFINITIONS
 ******************************************************************************/

/******************************************************************************
 **    inner FUNCTION DEFINITIONS
 ******************************************************************************/

/******************************************************************************
 **    FUNCTION DEFINITIONS
 ******************************************************************************/

GErrc cbus_service_message_register(cbus_service_t service, cbus_message_type_t message_type, cbus_message_id message_id, cbus_service_on_message_func on_message, GPTR opaque)
{
    if (!service || (message_type == CBUS_MSG_TYPE_Unknown) || (!on_message))
    {
        return G_ErrBadParameter;
    }

    GBOL has_success = GFALSE;

    endpoint_info_t* endpoint_array= service->endpoint_array;
    cbus_message_info_t msg_info;
    msg_info.message_id = message_id;
    msg_info.message_type = message_type;
    msg_info.on_message = on_message;
    msg_info.opaque = opaque;

    for (size_t i = 0; i < service->endpoint_array_count; i++)
    {
        GErrc ret = cbus_endpoint_register_message(endpoint_array[i].endpoint, &msg_info);

        if (G_OK == ret)
        {
            has_success = GTRUE;
        }
        else
        {
            LOGE("register message to endpoint(%d) failed(0x%08x)\n", i, ret);
            //todo process error
        }
    }
    
    return (has_success == GTRUE) ? G_OK : G_ErrUndefined;
}

GErrc cbus_service_message_register_category(cbus_service_t service, cbus_message_type_t message_type, cbus_service_on_message_func on_message, GPTR opaque)
{
    if (!service || (message_type == CBUS_MSG_TYPE_Unknown) || (!on_message))
    {
        return G_ErrBadParameter;
    }

    GBOL has_success = GFALSE;

    endpoint_info_t* endpoint_array= service->endpoint_array;

    for (size_t i = 0; i < service->endpoint_array_count; i++)
    {
        GErrc ret = cbus_endpoint_register_message_category(endpoint_array[i].endpoint, message_type, on_message, opaque);

        if (G_OK == ret)
        {
            has_success = GTRUE;
        }
        else
        {
            LOGE("register a category message to endpoint(%d) failed(0x%08x)\n", i, ret);
            //todo process error
        }
    }
    
    return (has_success == GTRUE) ? G_OK : G_ErrUndefined;
}

GErrc cbus_service_message_register_group(cbus_service_t service, const cbus_message_group_t* group)
{
    if (!service || !group)
    {
        return G_ErrBadParameter;
    }

    GBOL has_success = GFALSE;

    endpoint_info_t* endpoint_array= service->endpoint_array;

    for (size_t i = 0; i < service->endpoint_array_count; i++)
    {
        GErrc ret = cbus_endpoint_register_message_group(endpoint_array[i].endpoint, group);

        if (G_OK == ret)
        {
            has_success = GTRUE;
        }
        else
        {
            LOGE("register message group to endpoint(%d) failed(0x%08x)\n", i, ret);
            //todo process error
        }
    }
    
    return (has_success == GTRUE) ? G_OK : G_ErrUndefined;
}

GErrc cbus_service_message_unregister_message(cbus_service_t service, cbus_message_type_t message_type, GU32  message_id)
{
    if (!service || (message_type == CBUS_MSG_TYPE_Unknown))
    {
        return G_ErrBadParameter;
    }

    GBOL has_success = GFALSE;

    endpoint_info_t* endpoint_array= service->endpoint_array;

    for (size_t i = 0; i < service->endpoint_array_count; i++)
    {
        GErrc ret = cbus_endpoint_unregister_message(endpoint_array[i].endpoint, message_type, message_id);

        if (G_OK == ret)
        {
            has_success = GTRUE;
        }
        else
        {
            LOGE("unregister message from endpoint(%d) failed(0x%08x)\n", i, ret);
            //todo process error
        }
    }
    
    return (has_success == GTRUE) ? G_OK : G_ErrUndefined;
}

GErrc cbus_service_message_unregister_category(cbus_service_t service, cbus_message_type_t message_type)
{
    if (!service || (message_type == CBUS_MSG_TYPE_Unknown))
    {
        return G_ErrBadParameter;
    }

    GBOL has_success = GFALSE;

    endpoint_info_t* endpoint_array= service->endpoint_array;

    for (size_t i = 0; i < service->endpoint_array_count; i++)
    {
        GErrc ret = cbus_endpoint_unregister_message_category(endpoint_array[i].endpoint, message_type);

        if (G_OK == ret)
        {
            has_success = GTRUE;
        }
        else
        {
            LOGE("unregister a category of message from endpoint(%d) failed(0x%08x)\n", i, ret);
            //todo process error
        }
    }
    
    return (has_success == GTRUE) ? G_OK : G_ErrUndefined;
}

GErrc cbus_service_message_unregister_all(cbus_service_t service)
{
    if (!service)
    {
        return G_ErrBadParameter;
    }

    GBOL has_success = GFALSE;

    endpoint_info_t* endpoint_array= service->endpoint_array;

    for (size_t i = 0; i < service->endpoint_array_count; i++)
    {
        GErrc ret = cbus_endpoint_unregister_message_all(endpoint_array[i].endpoint);

        if (G_OK == ret)
        {
            has_success = GTRUE;
        }
        else
        {
            LOGE("unregister all message from endpoint(%d) failed(0x%08x)\n", i, ret);
            //todo process error
        }
    }
    
    return (has_success == GTRUE) ? G_OK : G_ErrUndefined;

}